package classes;

import java.awt.Color;
import java.util.ArrayList;

public class Shape extends ArrayList<Plane> {
	//
	// A shape is just a list of 3D triangular planes that we draw
	// All shapes are representations of these planes
	//
	/**
	 * This represents a shape in the 3d world
	 */
	private static final long serialVersionUID = 1L;
	public static final Shape	triangle(Vector V1, Vector V2, Vector V3) {
		Shape	S = new Shape();
		S.add(new Plane(V1, V2, V3));
		return S;
	}
	public static final Shape	axis(float radius) {
		float	NEG = -radius;
		float	POS = radius;
		
		Shape	S = new Shape();
		// Add the X axis		
		S.add(	
			new Wire(	
				new Vector(NEG, 0f, 0f),
				new Vector(POS, 0f, 0f)
			)
		);
		// Add the Y axis
		S.add(	
			new Wire(	
				new Vector(0f, NEG, 0f),
				new Vector(0f, POS, 0f)
			)
		);
		// Add the Z axis
		S.add(	
			new Wire(	
				new Vector(0f, 0f, NEG),
				new Vector(0f, 0f, POS)
			)
		);
		return S;
	}
	
	public static final Shape	box(Vector center, float radius) {
		//	North is negative z
		//	South is positive z
		//	West is negative x
		//	East is positive y
		//	floor is negative y
		//	ceiling is positive y
		
		Shape	S = new Shape();
		Vector	floorNW = new Vector(center.getX()-radius,	center.getY()-radius,	center.getZ()-radius);
		Vector	floorNE = new Vector(center.getX()+radius,	center.getY()-radius,	center.getZ()-radius);
		Vector	floorSW = new Vector(center.getX()-radius,	center.getY()-radius,	center.getZ()+radius);
		Vector	floorSE = new Vector(center.getX()+radius,	center.getY()-radius,	center.getZ()+radius);
		
		Vector	ceilingNW = new Vector(center.getX()-radius,	center.getY()+radius,	center.getZ()-radius);
		Vector	ceilingNE = new Vector(center.getX()+radius,	center.getY()+radius,	center.getZ()-radius);
		Vector	ceilingSW = new Vector(center.getX()-radius,	center.getY()+radius,	center.getZ()+radius);
		Vector	ceilingSE = new Vector(center.getX()+radius,	center.getY()+radius,	center.getZ()+radius);
		
		// Add the floor
		Plane	floorA,		floorB;
		Plane	ceilingA,	ceilingB;
		Plane	westWallA,	westWallB;
		Plane	eastWallA,	eastWallB;
		Plane	northWallA, northWallB;
		Plane	southWallA, southWallB;
		
		floorA = new Plane(floorNW, floorSE, floorSW);		// Keep rotations the same
		floorB = new Plane(floorNW, floorNE, floorSE);		// Keep rotations the same
		
		// Add the ceiling
		ceilingA = new Plane(ceilingNW, ceilingSE, ceilingSW);	// Keep rotations the same
		ceilingB = new Plane(ceilingNW, ceilingNE, ceilingSE);	// Keep rotations the same
		
		// Add the west wall
		westWallA	= new Plane(floorNW, floorSW, 	ceilingNW);
		westWallB	= new Plane(floorNW, ceilingNW,	ceilingSW);

		// Add the east wall
		eastWallA = new Plane(floorNE, floorSE, 	ceilingNE);
		eastWallB = new Plane(floorNE, ceilingNE,	ceilingSE);
		
		// Add the north wall
		northWallA = new Plane(floorNW, floorNE, 	ceilingNW);
		northWallB = new Plane(floorNE, ceilingNW,	ceilingNE);
		
		// Add the south wall
		southWallA = new Plane(floorSW, floorSE, 	ceilingSW);
		southWallB = new Plane(floorSE, ceilingSW,	ceilingSE);
		
		// Set A shapes color
		floorA.setFillColor(		translucent(	Color.red		)	);
		ceilingA.setFillColor(		translucent(	Color.blue		)	);
		westWallA.setFillColor(		translucent(	Color.green		)	);
		eastWallA.setFillColor(		translucent(	Color.orange	)	);
		northWallA.setFillColor(	translucent(	Color.yellow	)	);
		southWallA.setFillColor(	translucent(	Color.magenta	)	);

		// Set B shapes color
		floorB.setFillColor(		translucent(	Color.red		)	);
		ceilingB.setFillColor(		translucent(	Color.blue		)	);
		westWallB.setFillColor(		translucent(	Color.green		)	);
		eastWallB.setFillColor(		translucent(	Color.orange	)	);
		northWallB.setFillColor(	translucent(	Color.yellow	)	);
		southWallB.setFillColor(	translucent(	Color.magenta	)	);
		
		// Add all the shapes
		S.add(floorA);
		S.add(floorB);
		S.add(ceilingA);
		S.add(ceilingB);
		S.add(northWallA);
		S.add(northWallB);
		S.add(southWallA);
		S.add(southWallB);
		S.add(eastWallA);
		S.add(eastWallB);
		S.add(westWallA);
		S.add(westWallB);
		
		return S;
	}
	public static final Shape	wire(Vector P1, Vector P2) {
		Shape	S = new Shape();
		S.add(new Plane(P1, P2, P1));
		return S;
	}
	public static final	Shape	mesh(float pos[][]) {
		int		x, y;
		Vector	V1, V2, V3;
		Shape	S = new Shape();
		
		// First half of triangles
		for(x=0; x<pos.length-1; x++) {
			for(y=0; y<pos[0].length-1; y++) {
				V1 = new Vector(x,	y,		pos[x][y]);
				V2 = new Vector(x,	y+1,	pos[x][y+1]);
				V3 = new Vector(x,	y+1,	pos[x+1][y]);
				Plane	P = new Plane(V1, V2, V3);
				S.add(P);
			}
		}
		// Second half of triangles
		for(x=pos.length-1; x>0; x--) {
			for(y=pos[0].length-1; y>0; y--) {
				V1 = new Vector(x,	y,		pos[x][y]);
				V2 = new Vector(x,	y+1,	pos[x][y-1]);
				V3 = new Vector(x,	y+1,	pos[x-1][y]);
				Plane	P = new Plane(V1, V2, V3);
				S.add(P);
			}
		}
		return S;
	}
	
	public static final Color	translucent(Color C) {
//		Color	C2 = new Color(C.getRed(), C.getGreen(), C.getBlue(), C.getAlpha()/2);
		Color	C2 = new Color(C.getRed(), C.getGreen(), C.getBlue(), C.getAlpha());
		return	C2;
	}
}
